package com.sise.DP;

/**
 *      剑指 Offer 14- I. 剪绳子
 *
 *      给你一根长度为 n 的绳子，请把绳子剪成整数长度的 m 段（m、n都是整数，n>1并且m>1），
 *      每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少？
 *      例如，当绳子的长度是8时，我们把它剪成长度分别为2、3、3的三段，此时得到的最大乘积是18。
 */
public class _offer_14_cuttingRope {

    /**
     *      数学公式
     */
    public int cuttingRope(int n) {
        if (n == 1 || n == 2)
            return 1;
        if (n == 3)
            return 2;
        int sum = 1;
        while (n > 4) {
            sum *= 3;
            n -= 3;
        }
        return sum * n;
    }

    /**
     *      动态规划
     */
    public int cuttingRope_2(int n) {
        int[] dp = new int[n + 1];
        for (int i = 2; i <= n; i++){       // 0、1 切不成两段
            int curMax = 0;
            for (int j = 1; j < i; j++){            // 第二个 for 是作为切割点
                curMax = Math.max(curMax,           // 当拆分为两个数时候 j乘以i-j，当拆分为多个数字时候就为j乘以dp[i-j]（当n为i-j时候最大的乘积)
                                  Math.max(j * (i - j), j * dp[i - j])
                );
                dp[i] = curMax;
            }
        }
        return dp[n];
    }
}
